from time import process_time
from maix import uart, pinmap ,app ,time ,camera, display, image,touchscreen
from maix._maix.image import Circle

import cv2
import numpy as np

import enum

DEBUG_MODE = False  # 调试模式显示中间过程
CALIBRATION_MODE = False # 标定模式

A4_REAL_WIDTH = 21.0  # A4纸实际宽度(cm)
MIN_CONTOUR_AREA = 1200  # 最小轮廓面积阈值（过滤噪声）
FOCAL_length = 278.66 # 摄像头焦距

class ContourType(enum.Enum):
    Nothing = 1,
    Basic_squares = 2,
    Basic_circle = 3,
    Basic_triangle = 4,
    Extension_Two_and_One =5,
    Extension_Rotate =6
contoutrtype:ContourType = ContourType.Nothing



#创建一个Display对象
disp = display.Display()

cam = camera.Camera(320, 240) #(552, 368)
cam.skip_frames(30) # 跳过开头的30帧

#按键
ts = touchscreen.TouchScreen()
BASE_label_squares = "< BASE-squares"
size_BASE_label_squares = image.string_size(BASE_label_squares)
BASE_label_squares_btn_pos = [  0, 
                                0, 
                                8*2 + size_BASE_label_squares.width(), 
                                12 * 2 + size_BASE_label_squares.height()]

# 图像按键坐标映射到屏幕上的坐标
BASE_label_squares_btn_disp_pos = image.resize_map_pos(320, 240,disp.width(), disp.height(),
                            image.Fit.FIT_CONTAIN, BASE_label_squares_btn_pos[0], 
                            BASE_label_squares_btn_pos[1], BASE_label_squares_btn_pos[2], 
                            BASE_label_squares_btn_pos[3])

print(BASE_label_squares_btn_pos)
BASE_label_circle = "< BASE-circle"
size_BASE_label_circle = image.string_size(BASE_label_circle)
BASE_label_circle_btn_pos = [0, 
                            BASE_label_squares_btn_pos[1] +BASE_label_squares_btn_pos[3]+10, 
                            8*2 + size_BASE_label_circle.width(), 
                            12 * 2 + size_BASE_label_circle.height()]
print(BASE_label_circle_btn_pos)
# 图像按键坐标映射到屏幕上的坐标

BASE_label_circle_btn_disp_pos = image.resize_map_pos(320, 240,disp.width(), disp.height(),
                            image.Fit.FIT_CONTAIN, BASE_label_circle_btn_pos[0], 
                            BASE_label_circle_btn_pos[1], BASE_label_circle_btn_pos[2], 
                            BASE_label_circle_btn_pos[3])

BASE_label_triangle = "< BASE-triangle"
size_BASE_label_triangle = image.string_size(BASE_label_triangle)
BASE_label_triangle_btn_pos = [0, 
                            BASE_label_circle_btn_pos[1] +BASE_label_circle_btn_pos[3]+10, 
                            8*2 + size_BASE_label_triangle.width(), 
                            12 * 2 + size_BASE_label_triangle.height()]
print(BASE_label_triangle_btn_pos)


# 图像按键坐标映射到屏幕上的坐标
BASE_label_triangle_btn_disp_pos = image.resize_map_pos(320, 240,disp.width(), disp.height(), 
                            image.Fit.FIT_CONTAIN, BASE_label_triangle_btn_pos[0], 
                            BASE_label_triangle_btn_pos[1], BASE_label_triangle_btn_pos[2], 
                            BASE_label_triangle_btn_pos[3])


EXTE_label_two = "< E_one&two"
size_EXTE_label_two = image.string_size(EXTE_label_two)
EXTE_label_two_btn_pos = [0, 
                            BASE_label_triangle_btn_pos[1] +BASE_label_triangle_btn_pos[3]+10, 
                            8*2 + size_EXTE_label_two.width(), 
                            12 * 2 + size_EXTE_label_two.height()]
print(EXTE_label_two_btn_pos)


# 图像按键坐标映射到屏幕上的坐标
EXTE_label_two_btn_disp_pos = image.resize_map_pos(320, 240,disp.width(), disp.height(), 
                            image.Fit.FIT_CONTAIN, EXTE_label_two_btn_pos[0], 
                            EXTE_label_two_btn_pos[1], EXTE_label_two_btn_pos[2], 
                            EXTE_label_two_btn_pos[3])



EXTE_label_Rot = "< E_Rot"
size_EXTE_label_Rot = image.string_size(EXTE_label_Rot)
EXTE_label_Rot_btn_pos = [ 200, 
                            0, 
                            8*2 + size_EXTE_label_Rot.width(), 
                            12 * 2 + size_EXTE_label_Rot.height()]
print(EXTE_label_Rot_btn_pos)

# 图像按键坐标映射到屏幕上的坐标
EXTE_label_Rot_btn_disp_pos = image.resize_map_pos(320, 240,disp.width(), disp.height(), 
                            image.Fit.FIT_CONTAIN, EXTE_label_Rot_btn_pos[0], 
                            EXTE_label_Rot_btn_pos[1], EXTE_label_Rot_btn_pos[2], 
                            EXTE_label_Rot_btn_pos[3])








def is_in_button(x, y, btn_pos):
    return x > btn_pos[0] and x < btn_pos[0] + btn_pos[2] and y > btn_pos[1] and y < btn_pos[1] + btn_pos[3]
#按键END


### 标定 
def calibrate_camera(img,known_distance, known_width):
    """
    摄像头标定：计算焦距f
    :param known_distance: 已知距离(cm)
    :param known_width: 已知物体实际宽度(cm)
    """
    frame = img
    contour,_ = detect_a4_contour(frame)
    if contour is None:
        print("标定失败：未检测到A4纸")
        return None
    if DEBUG_MODE:
        print(f"contour:{contour}")
    # 计算像素宽度
    pixel_width = calculate_pixel_width(contour)

    # 计算焦距f = (像素宽度 * 已知距离) / 实际宽度
    focal_length = (pixel_width * known_distance) / known_width
    print(f"标定完成: 焦距f={focal_length:.2f}像素")
    return focal_length

def calculate_pixel_width(contour):
    """
    使用最小外接矩形计算短边
    """
    rect = cv2.minAreaRect(contour)
    width, height = rect[1]

    distance = min(width, height)
    # print(f"底边 distance: {distance}")
    return   distance# 直接返回短边长度
### 标定END

### a4边框识别 和测距
def detect_a4_contour(image):
    """
    检测A4纸轮廓
    """
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 自适应阈值处理 - 增强黑色边框
    thresh = cv2.adaptiveThreshold(
        gray, 255,
        cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY_INV, 59, 20
    )
    thresh_copy = thresh.copy()
    kernel = np.ones((3, 3), np.uint8)
    mask = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    if DEBUG_MODE:
        print(f"检测到 {len(contours)} 个轮廓")
    # 4. 筛选A4纸轮廓（最大轮廓+四边形判断）
    if contours:
        # 按面积降序排序
        contours = sorted(contours, key=cv2.contourArea, reverse=True)
        if DEBUG_MODE:
            print(f"检测到contours  {len(contours)} 个轮廓")
        for cnt in contours:
            area =cv2.contourArea(cnt)
            if DEBUG_MODE:
                print(f"检测到 A4 轮廓 {area:.2f} 面积")
            if  area< MIN_CONTOUR_AREA:
                continue

            # 多边形逼近
            peri = cv2.arcLength(cnt, True)
            approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
            if DEBUG_MODE:
                print(f"len(approx){len(approx)}")
            # 四边形检测
            if len(approx) == 4:
                if DEBUG_MODE:
                    print(f"approx{approx}")
                return approx,thresh_copy
    return None,thresh_copy
def calculate_distance(focal_length, pixel_width):
    """
    计算目标物距离D
    """
    return (focal_length * A4_REAL_WIDTH) / pixel_width
### a4边框识别END

### 透视变换
def perspective_transform(image, contour):
    """
    将A4纸区域透视变换为标准矩形
    """
    # 将轮廓点排序为（左上、右上、右下、左下）
    pts = contour.reshape(4, 2)
    rect = np.zeros((4, 2), dtype="float32")

    # 计算轮廓点中心
    center = np.mean(pts, axis=0)

    # 根据点与中心的相对位置排序
    for point in pts:
        if point[0] < center[0] and point[1] < center[1]:
            rect[0] = point  # 左上
        elif point[0] > center[0] and point[1] < center[1]:
            rect[1] = point  # 右上
        elif point[0] > center[0] and point[1] > center[1]:
            rect[2] = point  # 右下
        else:
            rect[3] = point  # 左下

    # 计算目标矩形尺寸（保持A4比例）
    width = max(
        np.linalg.norm(rect[0] - rect[1]),
        np.linalg.norm(rect[2] - rect[3])
    )
    height = max(
        np.linalg.norm(rect[0] - rect[3]),
        np.linalg.norm(rect[1] - rect[2])
    )

    # 创建目标点
    dst = np.array([
        [0, 0],
        [width - 1, 0],
        [width - 1, height - 1],
        [0, height - 1]
    ], dtype="float32")

    # 计算变换矩阵
    M = cv2.getPerspectiveTransform(rect, dst)

    # 应用透视变换
    warped = cv2.warpPerspective(image, M, (int(width), int(height)))

    return warped
### 透视变换END
### 正方形
def detect_squares_in_a4(warped):
    inverted_gray = cv2.bitwise_not(warped)
    _, binary_img = cv2.threshold(inverted_gray, 160, 255, cv2.THRESH_BINARY)
    # 2. 轮廓检测
    if DEBUG_MODE:
        print("正在检测正方形...")
    contours, _ = cv2.findContours(binary_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    if DEBUG_MODE:
        print(f"检测到 {len(contours)} 个轮廓")
    squares = []
    for cnt in contours:
        # 3. 形状识别（四边形验证）
        peri = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)
        # 4. 正方形特征验证
        if len(approx) == 4 and is_square(approx):
            # 5. 边长计算
            side_length = calculate_side_length(approx)
            if side_length <2:
                continue
            # 6. 位置记录
            M = cv2.moments(cnt)
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
            squares.append({
                "contour": approx,
                "side_length": side_length,
                "center": (cX, cY)
            })
    if DEBUG_MODE:
        print(f"检测到 {len(squares)} 个正方形")
    #将squares 绘制在图像中 显示

    if len(squares) == 1:
        largest_square = max(squares, key=lambda x: x["side_length"])
        """
        将像素长度转换为实际厘米
        """
        pixel_diameter = largest_square["side_length"]
        if DEBUG_MODE:
            print(f"像素直径: {pixel_diameter:.2f} 像素")

        actual_diameter = (pixel_diameter / warped.shape[1]) * A4_REAL_WIDTH
        if DEBUG_MODE:
            print(f"实际直径: {actual_diameter:.2f} cm")
        return warped ,actual_diameter
    return warped ,None
def is_square(contour, angle_threshold=15, aspect_threshold=0.15):
    """
    验证是否为正方形（基于角度和边长比例）
    """
    # 计算所有边长
    sides = []
    for i in range(4):
        pt1 = contour[i][0]
        pt2 = contour[(i+1)%4][0]
        sides.append(np.linalg.norm(pt2 - pt1))

    # 边长一致性检查
    max_side, min_side = max(sides), min(sides)
    aspect_ratio = abs(max_side - min_side) / ((max_side + min_side)/2)
    if aspect_ratio > aspect_threshold:
        return False

    # 角度检查（85-95度）
    for i in range(4):
        pt1 = contour[i][0]
        pt2 = contour[(i+1)%4][0]
        pt3 = contour[(i+2)%4][0]
        angle = calculate_angle(pt1, pt2, pt3)
        if not (85 <= angle <= 95):  # 允许±5度偏差
            return False
    return True
def calculate_angle(p1, p2, p3):
    """
    计算三点形成的角度
    """
    v1 = p1 - p2
    v2 = p3 - p2
    cos_theta = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
    return np.degrees(np.arccos(cos_theta))
def calculate_side_length(contour):
    """
    计算正方形边长（像素单位）
    """
    # 方法1：计算四条边的平均值
    sides = []
    for i in range(4):
        pt1 = contour[i][0]
        pt2 = contour[(i+1)%4][0]
        sides.append(np.linalg.norm(pt2 - pt1))
    avg_side = np.mean(sides)

    # 方法2：最小外接矩形法
    rect = cv2.minAreaRect(contour)
    min_side = min(rect[1])

    # 取两种方法的平均值提高精度
    return (avg_side + min_side) / 2
### 正方形END
### 三角形
def detect_triangles_in_a4(warped):
    """
    在A4纸区域内检测并测量三角形
    """
    inverted = cv2.bitwise_not(warped)
    _,binary_img = cv2.threshold(inverted,160,255,cv2.THRESH_BINARY)
    # 轮廓检测
    contours, _ = cv2.findContours(binary_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    if DEBUG_MODE:
        print(f"检测到 三角形 {len(contours)} 个轮廓")
    triangles = []
    for cnt in contours:
        # 多边形逼近
        peri = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)
        if DEBUG_MODE:
            print(f"检测到 三角形 {len(approx)} 个顶点")
        # 三角形验证（顶点数+几何特征）
        if len(approx) == 3 and is_equilateral_triangle(approx):
            # 边长计算
            side_length = calculate_triangle_side(approx)
            triangles.append({
                "contour": approx,
                "side_length": side_length,
                # "center": get_contour_center(cnt)
            })
    if DEBUG_MODE:
        print(f"检测到 {len(triangles)} 个三角形")
    if len(triangles) == 1:
    # 取面积最大的三角形（基本目标物在中心）
        largest_triangle = max(triangles, key=lambda t: cv2.contourArea(t["contour"]))
        pixel_side = largest_triangle["side_length"]
        if DEBUG_MODE:
            print(f"像素边长: {pixel_side:.2f} 像素")
        # 转换为实际尺寸
        a4_pixel_width = warped.shape[1]
        cm_side = (pixel_side / a4_pixel_width) * A4_REAL_WIDTH
        if DEBUG_MODE:
            print(f"实际边长: {cm_side:.2f} cm")
        return warped ,cm_side
    return warped,None
def is_equilateral_triangle(contour, angle_threshold=15, side_threshold=0.15):
    """
    验证等边三角形（基于角度和边长）
    """
    points = contour.reshape(3, 2)

    # 计算边长
    sides = [
        np.linalg.norm(points[1] - points[0]),
        np.linalg.norm(points[2] - points[1]),
        np.linalg.norm(points[0] - points[2])
    ]

    # 边长一致性检查
    max_side, min_side = max(sides), min(sides)
    aspect_ratio = abs(max_side - min_side) / ((max_side + min_side)/2)
    if aspect_ratio > side_threshold:
        return False

    # 角度检查（55-65度）
    for i in range(3):
        a, b, c = points[i], points[(i+1)%3], points[(i+2)%3]
        angle = calculate_angle(a, b, c)
        if not (55 <= angle <= 65):  # 等边三角形理论60度
            return False

    return True
def calculate_triangle_side(contour):
    """
    计算三角形边长（三种方法融合）
    """
    points = contour.reshape(3, 2)

    # 方法1：直接计算边长平均
    sides_direct = [
        np.linalg.norm(points[1] - points[0]),
        np.linalg.norm(points[2] - points[1]),
        np.linalg.norm(points[0] - points[2])
    ]
    avg_side = np.mean(sides_direct)

    # 方法2：最小外接圆半径法
    (cx, cy), radius = cv2.minEnclosingCircle(contour)
    circum_radius = radius
    theoretical_side = circum_radius * np.sqrt(3)  # 等边三角形外接圆公式

    # 方法3：面积法
    area = cv2.contourArea(contour)
    area_side = (4 * area / np.sqrt(3)) ** 0.5

    # 加权融合（优先直接测量）
    return (avg_side * 0.6 + theoretical_side * 0.3 + area_side * 0.1)
### 三角形END
### 圆形
# def detect_circle_in_a4(warped):
#     """
#     在A4纸区域内检测圆形并测量直径 修改完成
#     """
#     inverted_gray = cv2.bitwise_not(warped)
#     # 2. 圆形检测（使用霍夫圆变换）
#     circles = cv2.HoughCircles(
#         inverted_gray,
#         cv2.HOUGH_GRADIENT,
#         dp=2.8,
#         minDist=2,
#         param1=20,
#         param2=10,
#         minRadius=0,
#         maxRadius=300
#     )
#     print(f"len circles{len(circles)}")
#     # 3. 结果验证与处理
#     if circles is not None:
#         circles = np.uint16(np.around(circles))
#         circle = circles[0, 0]  # 取第一个检测到的圆
#         # 绘制检测结果
#         cv2.circle(warped, (circle[0], circle[1]), circle[2], (0, 255, 0), 4)
#         cv2.circle(warped, (circle[0], circle[1]), 2, (0, 0, 255), 3)
#         # 计算实际直径
#         pixel_diameter = 2 * circle[2]
#         print(f"圆像素直径: {pixel_diameter:.2f} 像素")
#         actual_diameter = (pixel_diameter / warped.shape[1]) * A4_REAL_WIDTH
#         print(f"实际直径: {actual_diameter:.2f} cm")
#         return warped, actual_diameter
#     return warped, None

def detect_circle_in_a4(warped):
    """
    在A4纸区域内检测圆形并测量直径 (基于轮廓分析)
    """
    # 1. 图像预处理

    inverted_gray = cv2.bitwise_not(warped)
    _, binary_img = cv2.threshold(inverted_gray, 160, 255, cv2.THRESH_BINARY)

    # 2. 查找并筛选轮廓
    contours, _ = cv2.findContours(binary_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    selected_contours = []

    # 基于图片内容设置更精确的筛选参数
    MIN_AREA = 30     # 圆形区域最小面积 (避免噪点)
    MAX_AREA = 6000   # 圆形区域最大面积 (避免误检整个A4区域)
    MIN_CIRCULARITY = 0.7  # 最低圆度
    MAX_CIRCULARITY = 1.3  # 最高圆度
    if DEBUG_MODE:
        print(f"Found {len(contours)} contours")

    for contour in contours:
        area = cv2.contourArea(contour)
        perimeter = cv2.arcLength(contour, True)
        if DEBUG_MODE:
            print(f"Contour area: {area}")
            print(f"Contour perimeter: {perimeter}")
        if perimeter == 0:
            continue

        # 计算圆度
        circularity = (4 * np.pi * area) / (perimeter ** 2)
        if DEBUG_MODE:
            print(f"circularity: {circularity}")

        # 筛选条件 - 根据图片中可能的圆形特征调整
        if (MIN_AREA <= area <= MAX_AREA and
            MIN_CIRCULARITY <= circularity <= MAX_CIRCULARITY):
            if DEBUG_MODE:
                print("符合条件")
            (x, y), radius = cv2.minEnclosingCircle(contour)
            center = (int(x), int(y))
            diameter = 2 * radius


            # 保存符合要求的轮廓
            selected_contours.append(contour)
            if DEBUG_MODE:
                print(f"Found circle - Area: {area:.2f}, Circularity: {circularity:.2f}, "
                    f"Center: ({x:.1f}, {y:.1f}), Diameter: {diameter:.2f}px")

            # 计算实际直径
            pixel_diameter = diameter * circularity
            if DEBUG_MODE:
                print(f"圆像素直径: {pixel_diameter:.2f} 像素")
            actual_diameter = (pixel_diameter / warped.shape[1]) * A4_REAL_WIDTH
            if DEBUG_MODE:
                print(f"实际直径: {actual_diameter:.2f} cm")
            return warped,actual_diameter
    return warped,None       
### 圆形END

### 发挥题
def detect_and_measure_squares(warped_a4):
    """
    检测并测量A4纸上的正方形
    """
    inverted_gray = cv2.bitwise_not(warped_a4)

    _, binary_img = cv2.threshold(inverted_gray, 190, 255, cv2.THRESH_BINARY)##85   ##190 用于双不旋转
    


    # 第一次闭运算：连接断裂部分
    closed1 = cv2.morphologyEx(binary_img, cv2.MORPH_CLOSE, np.ones((3,3), np.uint8))
    # cv2.imshow("Closed1", closed1)
    # 第二次开运算：消除残留噪声
    opened = cv2.morphologyEx(closed1, cv2.MORPH_OPEN, np.ones((1,1), np.uint8))
    # cv2.imshow("Opened", opened)



    # 2. 轮廓检测
    contours, _ = cv2.findContours(opened, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    print(f"len contours:{len(contours)}")

    squares = []
    for cnt in contours:
        # 3. 形状识别（四边形验证）
        peri = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.04 * peri, True)

        # 4. 正方形特征验证
        if len(approx) == 4 and is_square(approx,aspect_threshold=0.3):
            # 5. 边长计算
            side_length = calculate_side_length(approx)

            # 6. 位置记录
            M = cv2.moments(cnt)
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
            squares.append({
                "contour": approx,
                "side_length": side_length,
                "center": (cX, cY)
            })
    if DEBUG_MODE:
        print(f"检测到 {len(squares)} 个正方形")
    return squares



def find_min_area_square(squares):
    """识别最小面积的正方形"""
    if not squares:
        return None
    min_square = min(squares, key=lambda x: x["side_length"])
    return min_square
def convert_to_cm(pixel_length, warped_image):
    """
    将像素长度转换为实际厘米
    """
    a4_pixel_width = warped_image.shape[1]
    pixel_to_cm_ratio = A4_REAL_WIDTH / a4_pixel_width
    return pixel_length * pixel_to_cm_ratio

### 发挥题END


print("now_start")
while not  app.need_exit():
    text = "Noting"
    t = time.ticks_ms()

    #扫描按键
    x, y, pressed = ts.read()
    # print(x,y,pressed)
    if pressed == True and is_in_button(x, y, BASE_label_squares_btn_disp_pos):
        contoutrtype = ContourType.Basic_squares
        # print('111111')
    elif pressed == True and is_in_button(x, y, BASE_label_circle_btn_disp_pos):
        contoutrtype = ContourType.Basic_circle
        # print('222222')
    elif pressed == True and is_in_button(x, y, BASE_label_triangle_btn_disp_pos):
        # print('33333')
        contoutrtype = ContourType.Basic_triangle
    elif pressed == True and is_in_button(x, y, EXTE_label_two_btn_disp_pos):
        # print('33333')
        contoutrtype = ContourType.Extension_Two_and_One
    elif pressed == True and is_in_button(x, y, EXTE_label_Rot_btn_disp_pos):
        # print('33333')
        contoutrtype = ContourType.Extension_Rotate         





    #扫描按键END    



    #1读取图像
    img = cam.read() #默认输出RGB
    img_show = img
    img_cv2 = image.image2cv(img)
    #2标定模式
    if CALIBRATION_MODE:
    #标定 得到 焦距值 focal_length
    # 摄像头标定（在已知距离150cm处标定）
        focal_length = calibrate_camera(img_cv2,known_distance=150, known_width=A4_REAL_WIDTH)
        if focal_length is None:
            print("标定失败，无法进行距离测量")
            continue
        print(f"焦距值: {focal_length:.2f} 像素")
    #3测量模式
    else:
        # 3.0 检测A4纸轮廓
        contour,threth__ = detect_a4_contour(img_cv2)
        if DEBUG_MODE:
            print(f"检测A4纸轮廓点: {contour}")
        if contour is not None:
            imgcv2_copy = img_cv2.copy()
            threth__copy = threth__.copy()

            # 计算像素宽度
            pixel_width = calculate_pixel_width(contour)
            if DEBUG_MODE:
                print(f"pixel_width: {pixel_width}")
            # 计算距离D
            distance = calculate_distance(FOCAL_length, pixel_width)
            print(f"distance:{distance}")
            
            # 3.1 透视变换：将A4纸区域校正为正面视图
            warped = perspective_transform(threth__copy, contour)
            warped_copy = warped.copy()

            type_text = " "
            diameter_text = 0.0            
            if contoutrtype == ContourType.Basic_squares:
                warped_img, actual_diameter = detect_squares_in_a4(warped_copy)
                if actual_diameter is not None:
                    print(f"正方形边长: {actual_diameter:.2f} cm")
                    type_text = "squares"
                    diameter_text = actual_diameter

                    text = f"Base,D:{distance:.2f},{type_text},diameter:{diameter_text:.2f}"
            elif contoutrtype == ContourType.Basic_triangle:        
                warped_img, actual_diameter = detect_triangles_in_a4(warped_copy)
                if actual_diameter is not None:
                    print(f"三角形边长: {actual_diameter:.2f} cm")
                    type_text = "triangles"
                    diameter_text = actual_diameter
                    text = f"Base,D:{distance:.2f},{type_text},diameter:{diameter_text:.2f}"
            elif contoutrtype == ContourType.Basic_circle:          
                warped_img, actual_diameter = detect_circle_in_a4(warped_copy)
                if actual_diameter is not None:
                    print(f"圆形直径: {actual_diameter:.2f} cm")
                    type_text = "circle"
                    diameter_text = actual_diameter
                    text = f"Base,D:{distance:.2f},{type_text},diameter:{diameter_text:.2f}"
            elif contoutrtype == ContourType.Extension_Two_and_One: 
                squares = detect_and_measure_squares(warped)
                if squares is not None:
                    if DEBUG_MODE:
                        print(f'lensquares:{len(squares)}')
                    min_square = find_min_area_square(squares)
                    if min_square is not None:
                        # print(f'min_square:{min_square}')
                        pixel = min_square["side_length"]
                        actual_diameter = convert_to_cm(min_square["side_length"], warped)
                        print(f"最小边长: {actual_diameter:.2f} cm")
                        diameter_text = actual_diameter
                        text = f"EXTERN,D:{distance:.2f},diameter:{diameter_text:.2f}"
            elif contoutrtype == ContourType.Extension_Rotate  :
                squares = detect_and_measure_squares(warped)
                if squares is not None:
                    if DEBUG_MODE:
                        print(f'lensquares:{len(squares)}')
                    min_square = find_min_area_square(squares)
                    if min_square is not None:
                        # print(f'min_square:{min_square}')
                        pixel = min_square["side_length"]
                        actual_diameter = convert_to_cm(min_square["side_length"], warped)
                        print(f"最小边长: {actual_diameter:.2f} cm")
                        diameter_text = actual_diameter
                        text = f"EXTERN,diameter:{diameter_text:.2f}"

            
    img_show = image.cv2image(img_cv2)

    img_show.draw_string(10,200,text,color = image.Color.from_rgb(255,0,0),scale= 1.0)
    

    # #按键显示
    img_show.draw_string(8 +BASE_label_squares_btn_pos[0] , 
                        12+BASE_label_squares_btn_pos[1],
                        BASE_label_squares , 
                        image.COLOR_WHITE)
    img_show.draw_rect(BASE_label_squares_btn_pos[0], BASE_label_squares_btn_pos[1],
                 BASE_label_squares_btn_pos[2], BASE_label_squares_btn_pos[3],  image.COLOR_WHITE, 2)

    img_show.draw_string(8+BASE_label_circle_btn_pos[0], 
                        12+BASE_label_circle_btn_pos[1],
                        BASE_label_circle , 
                        image.COLOR_WHITE)
    img_show.draw_rect(BASE_label_circle_btn_pos[0], BASE_label_circle_btn_pos[1],
                 BASE_label_circle_btn_pos[2], BASE_label_circle_btn_pos[3],  image.COLOR_WHITE, 2)

    img_show.draw_string(8+BASE_label_triangle_btn_pos[0],
                         12+BASE_label_triangle_btn_pos[1],
                         BASE_label_triangle , 
                         image.COLOR_WHITE)
    img_show.draw_rect(BASE_label_triangle_btn_pos[0], BASE_label_triangle_btn_pos[1],
                 BASE_label_triangle_btn_pos[2], BASE_label_triangle_btn_pos[3],  image.COLOR_WHITE, 2)

    img_show.draw_string(8+EXTE_label_two_btn_pos[0],
                         12+EXTE_label_two_btn_pos[1],
                         EXTE_label_two , 
                         image.COLOR_WHITE)
    img_show.draw_rect(EXTE_label_two_btn_pos[0], EXTE_label_two_btn_pos[1],
                 EXTE_label_two_btn_pos[2], EXTE_label_two_btn_pos[3],  image.COLOR_WHITE, 2)


    img_show.draw_string(8+EXTE_label_Rot_btn_pos[0],
                         12+EXTE_label_Rot_btn_pos[1],
                         EXTE_label_Rot , 
                         image.COLOR_WHITE)
    img_show.draw_rect(EXTE_label_Rot_btn_pos[0], EXTE_label_Rot_btn_pos[1],
                 EXTE_label_Rot_btn_pos[2], EXTE_label_Rot_btn_pos[3],  image.COLOR_WHITE, 2)



    disp.show(img_show)      



















